/*
 * @Author: sean
 * @Date:   2020-06-01 12:29:51
 * @Last Modified by:   sean
 * @Last Modified time: 2020-06-19 20:42:58
 */
export default class util {
  /**
   * 判断是否为对象
   * @return {Boolean} [description]
   */
  static is_object(input) {
    return Object.prototype.toString.call(input) === '[object Object]';
  }

  /**
   * 判断是否是浏览器
   * @return {[type]} [description]
   */
  static in_browser() {
    return typeof window !== 'undefined';
  }
  /**
   * 判断你是否为空
   * @param  {[type]} $obj [description]
   * @return {[type]}      [description]
   */
  static empty($obj) {
    // 检验非数组/对象类型  EX：undefined   null  ''  根据自身要求添加其他适合的为空的值  如：0 ,'0','  '  等
    if (!$obj && $obj !== 0 && $obj !== '') return true;
    if (typeof $obj === 'string') {
      // 移除字符串中所有 ''
      $obj = $obj.replace(/\s*/g, '');
      if ($obj === '') return true;
    }
    return (Array.isArray($obj) && $obj.length === 0) || (Object.prototype.isPrototypeOf($obj) && Object.keys($obj).length === 0);
  }

  /**
   * 判断是否为数组
   * @param  {[type]}  input [description]
   * @return {Boolean}       [description]
   */
  static is_array(input) {
    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
  }

  /**
   * 判断是否为日期
   * @param  {[type]}  input [description]
   * @return {Boolean}       [description]
   */
  static is_date(input) {
    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
  }

  /**
   * 判断是否为数字
   * @param  {[type]}  input [description]
   * @return {Boolean}       [description]
   */
  static is_number(input) {
    return input instanceof Number || Object.prototype.toString.call(input) === '[object Number]';
  }

  /**
   * 判断是否为自字符串
   * @param  {[type]}  input [description]
   * @return {Boolean}       [description]
   */
  static is_string(input) {
    return input instanceof String || Object.prototype.toString.call(input) === '[object String]';
  }

  /**
   * 判断是否为布尔值
   * @param  {[type]}  input [description]
   * @return {Boolean}       [description]
   */
  static is_boolean(input) {
    return typeof input == 'boolean';
  }

  /**
   * 判断是否为函数
   * @param  {[type]} input [description]
   * @return {[type]}       [description]
   */
  static is_function(input) {
    return typeof input == 'function';
  }

  /**
   * 判断是否为空
   * @param  {[type]}  input [description]
   * @return {Boolean}       [description]
   */
  static is_null(input) {
    return input === undefined || input === null;
  }

  /**
   * 判断是否为数组
   * @param  {[type]}  o [description]
   * @return {Boolean}   [description]
   */
  static get_shift(data, is_error = false) {
    if (data) {
      return Object.keys(data).shift();
    } else {
      return false;
    }
  }

  /**
   * 获取实例化
   * @param  {[type]} component [description]
   * @param  {Object} props     [description]
   * @param  {Object} data      [description]
   * @param  {[type]} parent    [description]
   * @param  {[type]} el        [description]
   * @return {[type]}           [description]
   */
  static get_instance(Component, props = {}, data = {}, parent = null, el = null) {
    let instance = new Component({
      propsData: props,
      parent: parent,
      data() {
        return data;
      },
      el: el || document.createElement('div')
    });
    return instance;
  }

  /**
   * 事件绑定
   * @param {any} element  绑定dom
   * @param {any} event    事件类型
   * @param {any} listener 方法
   */
  static add_event(element, event, listener, bubble = false) {
    if (element.addEventListener) {
      element.addEventListener(event, listener, bubble);
    } else if (element.attachEvent) {
      element.attachEvent('on' + event, listener);
    } else {
      element['on' + event] = listener;
    }
  }

  /**
   * [is_plainObject description]
   * @param  {[type]}  obj [description]
   * @return {Boolean}     [description]
   */
  static is_plainObject(obj) {
    if (obj && Object.prototype.toString.call(obj) === '[object Object]' && obj.constructor === Object && !hasOwnProperty.call(obj, 'constructor')) {
      var key;
      for (key in obj) {}
      return key === undefined || hasOwnProperty.call(obj, key);
    }
    return false;
  }
  /**
   * [deepObjectMerge description]
   * @param  {[type]} FirstOBJ  [description]
   * @param  {[type]} SecondOBJ [description]
   * @return {[type]}           [description]
   */
  static deepObjectMerge(FirstOBJ, SecondOBJ) { // 深度合并对象
    for (var key in SecondOBJ) {
      FirstOBJ[key] = FirstOBJ[key] && FirstOBJ[key].toString() === '[object Object]'
        ? this.deepObjectMerge(FirstOBJ[key], SecondOBJ[key]) : FirstOBJ[key] = SecondOBJ[key];
    }
    return FirstOBJ;
  }
  /**
   * 扩展合并对象
   * @return {[type]} [description]
   */
  static extend() {
    var options;
    var name;
    var src;
    var copy;
    var copyIsArray;
    var clone;
    var target = arguments[0] || {};
    var i = 1;
    var length = arguments.length;
    var deep = false;
    if (typeof target === 'boolean') {
      deep = target;
      target = arguments[1] || {};
      i = 2;
    }
    if (typeof target !== 'object' && !this.is_function(target)) {
      target = {};
    }
    if (length === i) {
      target = this;
      --i;
    }
    for (; i < length; i++) {
      if ((options = arguments[i]) != null) {
        for (name in options) {
          src = target[name];
          copy = options[name];
          if (src === copy) {
            continue;
          }
          if (deep && copy && (this.is_plainObject(copy) || (copyIsArray = this.is_array(copy)))) {
            if (copyIsArray) {
              copyIsArray = false;
              clone = src && this.is_array(src) ? src : [];
            } else {
              clone = src && this.is_plainObject(src) ? src : {};
            }
            target[name] = this.extend(deep, clone, copy);
          } else if (copy !== undefined) {
            target[name] = copy;
          }
        }
      }
    }
    return target;
  }

  /**
   * 深层拷贝
   * @param  {[type]} data [description]
   * @return {[type]}      [description]
   */
  static copy(data) {
    let copyOne = null;
    if (this.is_object(data)) {
      copyOne = {};
      for (const key in data) {
        copyOne[key] = this.copy(data[key]);
      }
    } else if (this.is_array(data)) {
      copyOne = [];
      for (const index of data) {
        copyOne.push(this.copy(index));
      }
    } else {
      copyOne = data;
    }
    return copyOne;
  }
}
